var Web3 = require("web3");
var Tx = require('ethereumjs-tx');
const keythereum = require("keythereum");

// 创建web3对象
var web3 = new Web3();
// 连接到以太坊节点
 web3.setProvider(new Web3.providers.HttpProvider("http://192.168.1.89:8545"));
//web3.setProvider(new Web3.providers.HttpProvider("http://localhost:8545"));


var chainId=123456;
var from = "0x471912d13bbe0a91aaa553af4af048885943bd61"
//from="0x87330f033327D1981e134d14686645B43D20Ad7d"
var keyObject = {"address":"471912d13bbe0a91aaa553af4af048885943bd61","crypto":{"cipher":"aes-128-ctr","ciphertext":"b6a18faaa6174a1959cf7e106ddfebee6ee34651115ac9313be25d82ef5aa8a1","cipherparams":{"iv":"65d705bb1c3c50662b5cb894e32abb9b"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"f264c0f89b48188bf933cdbd00c66e2581a178e6036a938d894d8ef6bba3d3e2"},"mac":"f9cc8d74b991f2e58ddd1a14d7c99d8b2688514d43befeadf4e4b8611fd5a7c5"},"id":"43276613-4052-42b3-b99e-96d0630094e1","version":3}
//keyObject={"address":"87330f033327d1981e134d14686645b43d20ad7d","crypto":{"cipher":"aes-128-ctr","ciphertext":"5551d9400be65830c67c3580a8ca0dc0d5b9aa5b4e87fd047b770251af22bac0","cipherparams":{"iv":"b5cebb0e8285ff8452c4112c0be254fa"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"e6a81758da010c4d3e7204988511f169b6cdcbaee6bbf63d06d2f9cc0b4f3af7"},"mac":"2dd92306e53f262ab34338d588646ea0133d21579415620a70a5c5d96c38dd38"},"id":"bcfaee1e-ebb5-4f6b-957b-1658b2c16389","version":3}
var privKey = keythereum.recover("123456789", keyObject)

var to="0x36b6138de4344cedc01aeca326d8dcd1b7cfc62d"
//to="0x384eC9ea3Bd8AB4a355B0E170F0c225d43713D7C"
var owner = from/* var of type address here */;
var contract = web3.eth.contract([{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_supply","type":"uint256"},{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_decimals","type":"uint8"},{"name":"owner","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}]);

var _supply = 1000000/* var of type uint256 here */;
var _name = '二逼二逼币'/* var of type string here */;
var _symbol = 'SB' /* var of type string here */;
var _decimals = 0/* var of type uint8 here */;
var contractData = contract.new.getData(
    _supply,
    _name,
    _symbol,
    _decimals,
    owner,
    {
        data: '0x6080604052600060035534801561001557600080fd5b5060405161074a38038061074a8339810180604052810190808051906020019092919080518201929190602001805182019291906020018051906020019092919080519060200190929190505050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561009f57600080fd5b6000851115156100ae57600080fd5b8460038190555084600460008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550836000908051906020019061010f92919061014c565b50826001908051906020019061012692919061014c565b5081600260006101000a81548160ff021916908360ff16021790555050505050506101f1565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061018d57805160ff19168380011785556101bb565b828001600101855582156101bb579182015b828111156101ba57825182559160200191906001019061019f565b5b5090506101c891906101cc565b5090565b6101ee91905b808211156101ea5760008160009055506001016101d2565b5090565b90565b61054a806102006000396000f30060806040526004361061006d576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde0314610072578063313ce5671461010257806370a082311461013357806395d89b411461018a578063a9059cbb1461021a575b600080fd5b34801561007e57600080fd5b50610087610267565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100c75780820151818401526020810190506100ac565b50505050905090810190601f1680156100f45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561010e57600080fd5b50610117610305565b604051808260ff1660ff16815260200191505060405180910390f35b34801561013f57600080fd5b50610174600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610318565b6040518082815260200191505060405180910390f35b34801561019657600080fd5b5061019f610330565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156101df5780820151818401526020810190506101c4565b50505050905090810190601f16801561020c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561022657600080fd5b50610265600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506103ce565b005b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102fd5780601f106102d2576101008083540402835291602001916102fd565b820191906000526020600020905b8154815290600101906020018083116102e057829003601f168201915b505050505081565b600260009054906101000a900460ff1681565b60046020528060005260406000206000915090505481565b60018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156103c65780601f1061039b576101008083540402835291602001916103c6565b820191906000526020600020905b8154815290600101906020018083116103a957829003601f168201915b505050505081565b80600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205411151561041b57600080fd5b80600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555080600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a350505600a165627a7a72305820d8ed08752d22024e88d829004f1eb6b6086ec1ed26a8417c9ac8a636f2fa1f860029'
    });

// Construct the raw transaction
const gasPrice = 1000000000;
const gasPriceHex = web3.toHex(gasPrice);
console.log("gas Price "+gasPrice)
const gasLimitHex = web3.toHex(1000000);
var nonce = web3.eth.getTransactionCount(from);
var nonceHex = web3.toHex(nonce);

var rawTransaction = {
    "from": from,
    "nonce": nonceHex,
    "gasPrice": gasPriceHex,
    "gasLimit": gasLimitHex,
    "data": contractData,
    "chainId": chainId
};

var tx = new Tx(rawTransaction);
tx.sign(privKey);
var serializedTx = tx.serialize();
var txHash = "";
web3.eth.sendRawTransaction('0x' + serializedTx.toString('hex'), function (err, hash) {
    if (!err) {
        txHash = hash;
        console.log(hash)
        waitForTransactionReceipt(hash);
    }
    else {
        console.log(err);
    }
});

function waitForTransactionReceipt(hash) {
    console.log('waiting for contract to be mined');
    const receipt = web3.eth.getTransactionReceipt(hash);
    // If no receipt, try again in 1s
    if (receipt == null) {
        setTimeout(function () {
            waitForTransactionReceipt(hash);
        }, 1000);
    } else {
        // The transaction was mined, we can retrieve the contract address
        console.log('contract address: ' + receipt.contractAddress);
        testContract(receipt.contractAddress,from,to);
    }
}

//转帐100块
function testContract(address,from,to) {
    // Reference to the deployed contract
    const token = contract.at(address);
    // Assert initial account balance, should be 100000
    const balance1 = token.balanceOf(from);
    console.log("合约转帐前"+from+"余额："+balance1);

    var count = web3.eth.getTransactionCount(from);
    var data = token.transfer.getData(to, 100);
    var rawTransaction = {
        "from": from,
        "nonce": web3.toHex(count),
        "gasPrice": "0x04e3b29200",
        "gasLimit": 60000,
        "to": address,
        "value": "0x0",
        "data": data,
        "chainId": chainId
    };

    var tx = new Tx(rawTransaction);
    tx.sign(privKey);
    var serializedTx = tx.serialize();

    web3.eth.sendRawTransaction('0x' + serializedTx.toString('hex'), function (err, hash) {
        if (err) {
            console.log(err);
            return;
        }
        // Log transaction, in case you want to explore
        console.log('tx: ' + hash);
        // Assert destination account balance, should be 100
        waitForTransactionReceipt2(hash,address,from,to)
    });
}

function waitForTransactionReceipt2(hash,address,from,to) {
    console.log('waiting for transfer to be mined');
    const receipt = web3.eth.getTransactionReceipt(hash);
    // If no receipt, try again in 1s
    if (receipt == null) {
        setTimeout(function () {
            waitForTransactionReceipt2(hash,address,from,to);
        }, 1000);
    } else {
        const token = contract.at(address);
        const balance2 = token.balanceOf(from);
        console.log("合约转帐后"+from+"余额："+balance2);
    }
}

